package moonlit.chill.pay.service.impl.ali;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayDataDataserviceBillDownloadurlQueryModel;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
import lombok.extern.slf4j.Slf4j;
import moonlit.chill.pay.cache.PayConfigDataCache;
import moonlit.chill.pay.constants.Constants;
import moonlit.chill.pay.service.PayStrategy;
import moonlit.chill.pay.util.AliPayClientUtil;
import moonlit.chill.pay.util.ZipUtil;
import moonlit.chill.pay.vo.PayConfig;
import moonlit.chill.pay.vo.PayResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

/**
 * @author MoonlitChill
 * @date 2024/4/15 15:48
 */
@Slf4j
@Service("aliBillStrategy")
public class AliBillStrategyServiceImpl implements PayStrategy {

    @Resource
    private PayConfigDataCache payConfigDataCache;

    @Autowired
    private AliPayClientUtil aliPayClientUtil;

    @Override
    public PayResult<List<String[]>> payForBill(String date) {
        PayConfig payConfig = payConfigDataCache.getPayConfig();
        AlipayClient aliPayClient = aliPayClientUtil.getAliPayClient(payConfig);
        AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
        model.setBillDate(date);
        model.setBillType("trade");
        request.setBizModel(model);
        if (StrUtil.isNotEmpty(payConfig.getAppAuthToken())){
            request.putOtherTextParam("app_auth_token", payConfig.getAppAuthToken());
        }
        PayResult<List<String[]>> result = new PayResult<>();
        try {
            int downLoadTryTime = 0;
            AlipayDataDataserviceBillDownloadurlQueryResponse response;
            if (payConfig.getAliType() == 0){
                response = aliPayClient.certificateExecute(request);
            } else {
                response = aliPayClient.execute(request);
            }
            while (!response.isSuccess() && downLoadTryTime < 3) {
                Thread.sleep(3000);
                downLoadTryTime++;
                if (payConfig.getAliType() == 0){
                    //证书模式
                    response = aliPayClient.certificateExecute(request);
                } else {
                    //密钥模式
                    response = aliPayClient.execute(request);
                }
            }
            if (response.isSuccess()) {
                ZipUtil.makdirs("");
                HttpUtil.downloadFile(response.getBillDownloadUrl(), FileUtil.file(payConfig.getDownPath()));
                ZipUtil.unzip(new File(payConfig.getDownPath() + payConfig.getUId() + "0156_" + date.replaceAll("-", "") + ".csv.zip"), payConfig.getDownPath());
                //从文件中读取CSV数据
                DataInputStream dataInputStream = new DataInputStream(Files.newInputStream(new File(payConfig.getDownPath() + payConfig.getUId() + "0156_" + date.replaceAll("-", "") + "_业务明细.csv").toPath()));
                //设置格式
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream, "GBK"));
                //去标头
                for (int i = 0; i < 5; i++) {
                    bufferedReader.readLine();
                }
                String rowRecord;
                List<String[]> list = new ArrayList<>();
                while ((rowRecord = bufferedReader.readLine()) != null) {
                    if ("#-----------------------------------------业务明细列表结束------------------------------------".equals(rowRecord)) {
                        bufferedReader.close();
                        result.setResult(list);
                        result.setSuccess(Boolean.TRUE);
                        return result;
                    }
                    String[] split = rowRecord.split(",");
                    list.add(split);
                }
            } else {
                result.error(response.getSubMsg(), Constants.PAY_FAIL_CODE);
            }
        } catch (Exception e) {
            result.errorWithException("下载账单失败", Constants.PAY_ERROR_CODE, e);
        }
        return result;
    }
}
